package com.ruoyi.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.ruoyi.business.domain.CarPackageAudit;
import com.ruoyi.business.domain.ServiceItem;
import com.ruoyi.business.mapper.ServiceItemMapper;
import com.ruoyi.business.service.*;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.system.service.ISysUserService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 养修服务项Service业务层处理
 * 
 * @author wolfcode
 * @date 2021-05-14
 */
@Service
public class ServiceItemServiceImpl implements IServiceItemService
{
    @Autowired
    private ServiceItemMapper serviceItemMapper;
    @Autowired
    private ICarPackageAuditService carPackageAuditService;
    @Autowired
    private IProcessService processService;
    @Autowired
    private IDefinitionNodeService definitionNodeService;
    /**
     * 查询养修服务项
     * 
     * @param id 养修服务项ID
     * @return 养修服务项
     */
    @Override
    public ServiceItem selectServiceItemById(Long id)
    {
        return serviceItemMapper.selectServiceItemById(id);
    }

    /**
     * 查询养修服务项列表
     * 
     * @param serviceItem 养修服务项
     * @return 养修服务项
     */
    @Override
    public List<ServiceItem> selectServiceItemList(ServiceItem serviceItem)
    {
        return serviceItemMapper.selectServiceItemList(serviceItem);
    }

    /**
     * 新增养修服务项
     * 
     * @param serviceItem 养修服务项
     * @return 结果
     */
    @Override
    public int insertServiceItem(ServiceItem serviceItem)
    {
        serviceItem.setCreateTime(DateUtils.getNowDate());
        if(ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())){
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);//设置初始化
        }
        return serviceItemMapper.insertServiceItem(serviceItem);
    }

    /**
     * 修改养修服务项
     * 
     * @param serviceItem 养修服务项
     * @return 结果
     */
    @Override
    public int updateServiceItem(ServiceItem serviceItem)
    {
        ServiceItem oldObj = selectServiceItemById(serviceItem.getId());
        //处于上架状态的商品不能修改
        if(ServiceItem.SALESTATUS_ON.equals(oldObj.getSaleStatus())){
            throw new BusinessException("上架服务项目不能修改，请下架后再修改");
        }else if(ServiceItem.AUDITSTATUS_AUDITING.equals(oldObj.getAuditStatus())){
            throw new BusinessException("服务项目正在审核中,不可修改");
        }
        //如果是审核通过，此时修改，需要将其状态变更为初始化
        if(ServiceItem.AUDITSTATUS_APPROVED.equals(oldObj.getAuditStatus())){
            serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_INIT);
        }
        serviceItem.setVersion(oldObj.getVersion());
        return serviceItemMapper.updateServiceItem(serviceItem);
    }
    /**
     * 删除养修服务项对象
     * 
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteServiceItemByIds(String ids)
    {
        return serviceItemMapper.deleteServiceItemByIds(Convert.toStrArray(ids));
    }
    /**
     * 下架
     *
     * @param id 需要下架的服务项ID
     * @return
     */
    @Override
    public int saleOff(Long id) {
        return serviceItemMapper.changeSaleStatus(id,ServiceItem.SALESTATUS_OFF);
    }
    /**
     * 上架
     * @param id 需要上架的服务ID
     * @return
     */
    @Override
    public int saleOn(Long id) {
        ServiceItem serviceItem = selectServiceItemById(id);
        //如果不是套餐，可以直接上架
        //如果是套餐，只有审核成功才能上架
        if(ServiceItem.CARPACKAGE_YES.equals(serviceItem.getCarPackage())
                && !ServiceItem.AUDITSTATUS_APPROVED.equals(serviceItem.getAuditStatus())){
            throw new BusinessException("套餐服务项需要审核通过之后才能上架");
        }
        return serviceItemMapper.changeSaleStatus(id,ServiceItem.SALESTATUS_ON);
    }
    /**
     * 查询上家的养修服务项列表
     *
     * @param serviceItem 养修服务项
     * @return 养修服务项集合
     */
    @Override
    public List<ServiceItem> selectAllSaleOnList(ServiceItem serviceItem) {
        return serviceItemMapper.selectAllSaleOnList(serviceItem);
    }

    @Override
    public int startAudit(Long id) {
        //  1.根据传入id查询服务项,服务项状态处于初始化才可能进行审核逻辑
        ServiceItem serviceItem = serviceItemMapper.selectServiceItemById(id);
        if (!ServiceItem.AUDITSTATUS_INIT.equals(serviceItem.getAuditStatus())){
            // 判断查询出来的状态是否等于0初始化 不等于抛出异常
            throw new BusinessException("非法操作,只有初始化状态的服务项才能发起审核");
        }
        //  2.修改服务项的状态,修改成审核中
        serviceItem.setAuditStatus(ServiceItem.AUDITSTATUS_AUDITING);
        serviceItemMapper.updateServiceItem(serviceItem);
        //  3.封装CarPackageAudit对象,把服务项转成json字符串,保存对象
        CarPackageAudit audit = new CarPackageAudit();
        audit.setServiceItemInfo(JSON.toJSONString(serviceItem));// 快照
        audit.setCreateBy(ShiroUtils.getUserId().toString());// 当前登录用户id
        carPackageAuditService.insertCarPackageAudit(audit);//保存到快照表
        //  4.启动流程实例(汽车套餐流程key(流程定义id),CarPackageAudit快照表的id作为业务key传入进去,把金额作为流程变量传进去),获得流程实例对象
        String businessKey = audit.getId().toString();
        Map<String,Object> variables = new HashMap<>();
        variables.put("money",serviceItem.getDiscountPrice().longValue());
        ProcessInstance processInstance = processService.startProcessInstance(CarPackageAudit.DEFINITION_KEY,businessKey,variables);
        //  5.获取到当前流程中正在执行的节点，根据节点的ID从数据表中查询对应的审核人
        Task currentTask = processService.getTaskByProcessInstanceId(processInstance.getId());//通过流程实例id获取当前的任务节点
        String taskDefinitionKey = currentTask.getTaskDefinitionKey();// 通过当前任务查询节点审核的id（如：shopOwnerAudit）
        List<SysUser> auditors = definitionNodeService.queryByTaskDefinitionKey(taskDefinitionKey);
        //  6.给到任务去设置候选人 ====> 候选人的信息存储起来
        List<String> auditorsName = new ArrayList<>();
        for (SysUser user : auditors) {
            //  给任务添加对应的审核人
            processService.addCandidateUser(currentTask,user.getUserId());
            //  把审核候选人的名称存起来
            auditorsName.add(user.getUserName());
        }
        //  7.需要获取到流程实例ID,设置到CarPackageAudit对象
        audit.setInstanceId(processInstance.getId());
        //  8.获取到审核人的信息,设置CarPackageAudit对象的auditors属性中
        audit.setAuditors(JSON.toJSONString(auditorsName));
        //  9.更新CarPackageAudit对象
        carPackageAuditService.updateCarPackageAudit(audit);
        return 1;
    }

    @Override
    public void updateServiceItemNoCondition(ServiceItem item) {
        serviceItemMapper.updateServiceItemNoCondition(item);
    }
}
